package com.alex.statistics.method.explorationAnalysis;

import com.alex.statistics.pojo.request.explorationAnalysis.ZScoreRequest;
import com.alex.statistics.pojo.result.explorationAnalysis.ZScoreResult;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class ZScoreMultiAnalyzer {


        private static final double DEFAULT_THRESHOLD = 3.0;

        public ZScoreResult detect(ZScoreRequest request) {
            List<Double> data = request.getData();
            double threshold = request.getThreshold() != null ?
                    request.getThreshold() : DEFAULT_THRESHOLD;

            double mean = calculateMean(data);
            double stdDev = calculateStdDev(data, mean);

            List<Integer> anomalies = new ArrayList<>();
            List<Double> zScores = new ArrayList<>();

            for (int i = 0; i < data.size(); i++) {
                double zScore = stdDev != 0 ? (data.get(i) - mean) / stdDev : 0;
                zScores.add(zScore);
                if (Math.abs(zScore) > threshold) {
                    anomalies.add(i);
                }
            }

            return new ZScoreResult(anomalies, zScores, mean, stdDev);
        }

        private double calculateMean(List<Double> data) {
            return data.stream().mapToDouble(Double::doubleValue).average().orElse(0);
        }

        private double calculateStdDev(List<Double> data, double mean) {
            double variance = data.stream()
                    .mapToDouble(x -> Math.pow(x - mean, 2))
                    .average()
                    .orElse(0);
            return Math.sqrt(variance);
        }
    }